import Component from '@teld/q-components/Tree';
import useMappingProps from 't/common/hooks/useMappingProps';
import {
  commonProps,
  fixNameSpace,
  pickOwnForBasicComponent,
} from 't/common/utils';
import { defineComponent, nextTick, ref, watch } from 'vue';
import styles from './index.module.scss';
import './index.scss';

export * from '@teld/q-components/Tree';

export default defineComponent({
  name: fixNameSpace(Component.name),
  props: {
    ...commonProps,
    ...Component.props,
    mockValue: {
      type: Array,
      default() {
        return [];
      },
    },
    nodes: {
      type: Array,
      default() {
        return [];
      },
    },
  },
  emits: ['nodeClick'],

  setup(props, { attrs, emit, expose, slots }) {
    const refComponent = ref();
    let noResult = '';
    const [mappingProps, mappingExpose] = useMappingProps(props, {
      getNodeLevelByKey() {
        return getNodeLevelByKey(...arguments);
      },
      getNodeByKey() {
        return refComponent.value.getNodeByKey(...arguments);
      },
      getTickedNodes() {
        return refComponent.value.getTickedNodes(...arguments);
      },
      getExpandedNodes() {
        return refComponent.value.getExpandedNodes(...arguments);
      },
      isExpanded() {
        return refComponent.value.isExpanded(...arguments);
      },
      expandAll() {
        return refComponent.value.expandAll(...arguments);
      },
      collapseAll() {
        return refComponent.value.collapseAll(...arguments);
      },
      setExpanded() {
        return refComponent.value.setExpanded(...arguments);
      },
      isTicked() {
        return refComponent.value.isTicked(...arguments);
      },
      setTicked() {
        return refComponent.value.setTicked(...arguments);
      },
    });

    expose(mappingExpose);

    if (!mappingProps.nodes) {
      mappingProps.nodes = [];
    }
    if (!Array.isArray(mappingProps.nodes)) {
      mappingProps.nodes = JSON.parse(mappingProps.nodes);
    }
    if (!mappingProps.ticked || !Array.isArray(mappingProps.ticked)) {
      delete mappingProps.ticked;
    }
    noResult =
      Array.isArray(mappingProps.nodes) && mappingProps.nodes.length === 0
        ? 'tr-tree-noResult'
        : '';

    watch(
      () => {
        return [mappingProps.nodes, mappingProps.ticked];
      },
      (nv, ov) => {
        if (!nv[0]) {
          mappingProps.nodes = [];
        }
        if (!Array.isArray(nv[0])) {
          mappingProps.nodes = JSON.parse(
            mappingProps.nodes.replaceAll('\r\n', ''),
          );
        }
        noResult =
          Array.isArray(mappingProps.nodes) && mappingProps.nodes.length === 0
            ? 'tr-tree-noResult'
            : '';
        if (
          nv[0].length != ov[0].length &&
          mappingProps.nodes &&
          Array.isArray(mappingProps.nodes) &&
          mappingProps.nodes.length > 0 &&
          mappingProps.defaultExpandAll
        ) {
          nextTick(() => {
            refComponent.value.expandAll();
          });
        }
        if (!mappingProps.ticked || !Array.isArray(mappingProps.ticked)) {
          delete mappingProps.ticked;
        }
      },
    );
    function getDifference(a, b) {
      const setB = new Set(b);
      const setA = new Set(a);

      if (a.length > b.length) {
        return a.filter(item => !setB.has(item));
      } else if (a.length < b.length) {
        return b.filter(item => !setA.has(item));
      }
      return [];
    }
    watch(
      () => {
        return mappingProps.ticked;
      },
      (nv, ov) => {
        if (nv.length > ov.length) {
          let data = getDifference(nv, ov);
          emit('nodeClick', { key: data, val: true });
        } else {
          let data = getDifference(nv, ov);
          emit('nodeClick', { key: data, val: false });
        }
      },
    );
    watch(
      () => {
        return mappingProps.selected;
      },
      (nv, ov) => {
        if (!nv) {
          emit('nodeClick', { key: ov, val: false });
        } else {
          emit('nodeClick', { key: nv, val: true });
        }
      },
    );
    //获取指定节点的父级
    function getNodeLevelByKey(key) {
      if (!key) {
        return;
      }
      let node = refComponent.value.getNodeByKey(key);
      //检查是否是叶节点
      // if (!node.children || node.children.length === 0) {
      return getLeafPath(
        node ? node[mappingProps.nodeKey] : null,
        mappingProps.nodes,
      );
      // }
    }
    function getLeafPath(nodeId, nodes, path = []) {
      for (let node of nodes) {
        // 将当前节点添加到路径中
        path.push(node);

        // 检查是否找到了目标叶节点
        if (
          node[mappingProps.nodeKey] === nodeId
          // &&(!node.children || node.children.length === 0)
        ) {
          return path; // 返回从根节点到叶节点的完整路径
        }

        // 如果当前节点有子节点，则递归搜索
        if (node[mappingProps.childrenKey]) {
          const result = getLeafPath(
            nodeId,
            node[mappingProps.childrenKey],
            path,
          );
          if (result) {
            return result; // 如果在子节点中找到了路径，直接返回
          }
        }
        // 回溯，移除当前节点，尝试其他分支
        path.pop();
      }
      return null; // 没有找到路径
    }
    const inDesign = !!window['fas']?.inDesign;

    return () => {
      return (
        <Component
          ref={refComponent}
          {...attrs}
          {...pickOwnForBasicComponent(mappingProps, Component.props, attrs)}
          filter={!inDesign && mappingProps.filter}
          class={['t-tree', styles.module, noResult]}
          v-show={mappingProps.visible}
          icon={`${TComponents?.IconList?.common ?? 'fas dx-icon'} ${TComponents?.IconList?.arrowRight ?? 'icon-t-arrow-right'}`}
          // v-slots={{ ...slots }}
        >
          {slots}
        </Component>
      );
    };
  },
});
